package com.tianbing.adlottery.helper;

/**
 * $RCSfile: SkinUtils.java,v $
 * $Revision: 1.8.2.4 $
 * $Date: 2001/04/06 05:31:24 $
 *
 * Copyright (C) 2000 CoolServlets.com. All rights reserved.
 *
 * ===================================================================
 * The Apache Software License, Version 1.1
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by
 *        CoolServlets.com (http://www.coolservlets.com)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Jive" and "CoolServlets.com" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please
 *    contact webmaster@coolservlets.com.
 *
 * 5. Products derived from this software may not be called "Jive",
 *    nor may "Jive" appear in their name, without prior written
 *    permission of CoolServlets.com.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL COOLSERVLETS.COM OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of CoolServlets.com. For more information
 * on CoolServlets.com, please see <http://www.coolservlets.com>.
 */

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.web.bind.ServletRequestUtils;

import com.jubao.ejb.business.UserBusiness;
import com.jubao.ejb.business.util.BusinessConstant;
import com.jubao.ejb.dao.CategoryDao;
import com.jubao.ejb.dao.StoreDao;
import com.jubao.ejb.dao.UserDao;
import com.jubao.ejb.entity.Category;
import com.jubao.ejb.entity.Store;
import com.jubao.ejb.entity.User;
import com.tianbing.adlottery.util.UserSession;

/**
 * A collection of utility methods for use in Jive WebSkins. Because these
 * methods make skin development much easier, skin authors should study them
 * carefully.
 * <p>
 * 
 * Three major areas of funtionality are provided:
 * <p>
 * <ol>
 * <li> Methods that simplify Authorization tasks:
 * <ul>
 * <li>{@link #getUserAuthorization(HttpServletRequest, HttpServletResponse)}
 * <li>{@link #getUserAuthorization(HttpServletRequest, HttpServletResponse, boolean)}
 * <li>{@link #setUserAuthorization(HttpServletRequest, HttpServletResponse, String, String, boolean)}
 * <li>{@link #removeUserAuthorization(HttpServletRequest, HttpServletResponse)}
 * </ul>
 * <p>
 * <li> Methods that get and set Session and cookie values.
 * <ul>
 * <li>{@link #getCookie(HttpServletRequest, String)}
 * <li>{@link #getCookieValue(HttpServletRequest, String)}
 * <li>{@link #invalidateCookie(HttpServletRequest, HttpServletResponse, String)}
 * <li>{@link #remove(HttpServletRequest, HttpServletResponse, String)}
 * <li>{@link #retrieve(HttpServletRequest, HttpServletResponse, String)}
 * <li>{@link #retrieve(HttpServletRequest, HttpServletResponse, String, boolean)}
 * <li>{@link #store(HttpServletRequest, HttpServletResponse, String, String)}
 * <li>{@link #store(HttpServletRequest, HttpServletResponse, String, String, int)}
 * <li>{@link #store(HttpServletRequest, HttpServletResponse, String, String, int boolean)}
 * </ul>
 * <p>
 * <li> Other methods.
 * <ul>
 * <li>{@link #dateToText(Date)}
 * <li>(@link #getLastVisisted(HttpServletRequest, HttpServletResponse)}
 * <li>(@link #getLastVisisted(HttpServletRequest, HttpServletResponse,
 * boolean)}
 * <li>{@link #isNewMessage(ForumMessage, long)}
 * <li>(@link #quoteOriginal(ForumMessage, String, int)}
 * </ul>
 * </ol>
 * 
 * All methods conform to the Servlet 1.1 and JSP 1.0 specs for maximum
 * compatibility with application servers. This may yield deprecation warnings
 * if you compile with a newer Servlet/JSP spec; these should be ignored. This
 * class will periodically be updated to the newer specs as app servers mature.
 */
public class SkinUtils {
	Logger logger = Logger.getLogger(SkinUtils.class.getName());

	/** Name of the authentication token (is stored in the user's session) */
	public static final String JIVE_AUTH_TOKEN = "userSession";// "jiveAuthorization";

	/** Name of the cookie used to store user info for auto-login purposes */
	public static final String JIVE_AUTOLOGIN_COOKIE = "autoLogin";// "jiveAutoLogin";

	/** Name of the last visited token (is stored in the user's session) */
	public static final String JIVE_LASTVISITED_TOKEN = "lastVisited";// "jiveLastVisited";

	public static final String JIVE_LASTVISITED_HORDE_TOKEN = "lastVisitedHorde";// "lastVisitedHorde";

	public static final String JIVE_HAS_CHECKED_AUTOLOGIN_TOKEN = "hasCheckedAutoLogin";// "hasCheckedAutoLogin";

	/** Name of the cookie used to store last visited timestamp */
	public static final String JIVE_LASTVISITED_COOKIE = "lastVisited";// "jiveLastVisited";

	// Time constants (in milliseconds)
	private static final long SECOND = 1000;

	private static final long MINUTE = 60 * SECOND;

	private static final long HOUR = 60 * MINUTE;

	private static final long DAY = 24 * HOUR;

	private static final long WEEK = 7 * DAY;

	// Default cookie time to live (in seconds).
	private static final int MAX_COOKIE_AGE = (int) (WEEK / 1000) * 8;

	// Days of the week
	private static final String[] DAYS_OF_WEEK = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
			"Saturday" };

	// SimpleDateFormat objects for use in the dateToText method
	private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("EEEE, MMM d 'at' h:mm a");

	private static final SimpleDateFormat yesterdayFormatter = new SimpleDateFormat("'Yesterday at' h:mm a");

	// "Tweakable" parameters for the cookie encoding. NOTE: changing these
	// and recompiling this class will essentially invalidate old cookies.
	private final static int ENCODE_XORMASK = 0x5A;

	private final static char ENCODE_DELIMETER = '\002';

	private final static char ENCODE_CHAR_OFFSET1 = 'A';

	private final static char ENCODE_CHAR_OFFSET2 = 'h';

	UserDao userDao;

	StoreDao storeDao;

	CategoryDao categoryDao;

	private UserBusiness userBusiness;

	private String rootUserId;

	/**
	 * Returns an Authorization token for the user. The following steps are
	 * performed to determine the token:
	 * <ol>
	 * 
	 * <li>Check the session for the existence of a Jive authorization token.
	 * If one is found, it is returned as we assume that the user has logged in
	 * and is authorized.
	 * <li>Check the Jive authorization cookie for a username and password. If
	 * found, attempt to create a Jive authorization token using that data. If
	 * successful, save the token to the session and return it. NOTE: This check
	 * can be skipped by setting <code>checkJiveCookie</code> to false.
	 * </ol>
	 * <p>
	 * 
	 * @param request
	 *            the HttpServletRequest object, known as "request" in a JSP
	 *            page.
	 * @param response
	 *            the HttpServletResponse object, known as "response" in a JSP
	 *            page.
	 * @param checkJiveCookie
	 *            a boolean that indicates whether or not we want to use a
	 *            cookie for authorization.
	 * @return the authorization token if authenticated, otherwise
	 *         <code>null</code>.
	 * @see UserSession
	 */
	public UserSession getUserAuthorization(HttpServletRequest request, HttpServletResponse response,
			boolean checkJiveCookie) {
		// we can get the session object from the request object:
		HttpSession session = request.getSession();

		// Check 1: check for the jive authentication token in the user's
		// session.
		UserSession authToken = (UserSession) session.getAttribute(JIVE_AUTH_TOKEN);
		if (authToken != null) {
			return authToken;
		}

		// Check 2: check the jive cookie for username and password, if we're
		// allowing that
		if (checkJiveCookie) {
			Cookie cookie = getCookie(request, JIVE_AUTOLOGIN_COOKIE);
			try {
				if (cookie != null) {
					// at this point, we found a cookie so grab the username &
					// password
					// from it, create an authorization token and store that in
					// the session
					String[] values = decodePasswordCookie(cookie.getValue());
					String emailAddr = values[0];
					String password = values[1];
					// try to validate the user based on the info from the
					// cookie
					// authToken =
					// authorizationFactory.getAuthorization(username,
					// password);

					// put that token in the user's session:
					// session.setAttribute(JIVE_AUTH_TOKEN, authToken);
					authToken = this.setUserAuthorization(request, response, emailAddr, password, true);
					// return the authorization token
					return authToken;
				}
			} catch (Exception e) {
				if (response != null) {
					// We want any exceptions in this block to be caught so that
					// an
					// anonymous authorization token can be returned. The
					// getAuthorzation(username,password) method above throws an
					// UnauthorizedException. In the case of this exception or
					// others,
					// the cookie holds invalid login info, so we should remove
					// it:
					cookie = new Cookie(JIVE_AUTOLOGIN_COOKIE, null);
					cookie.setMaxAge(0); // zero value causes cookie to be
					// deleted
					cookie.setPath("/");
					response.addCookie(cookie);
				}
			}
		}

		// Got this far, so return null.
		return null;
	}

	/**
	 * Returns an Authorization token for the user. This is a convenience method
	 * that that calls the other getUserAuthorization method with
	 * <code>checkJiveCookie</code set to true.
	 *
	 * @param request the HttpServletRequest object, known as "request" in a
	 *      JSP page.
	 * @param response The HttpServletResponse object, known as "response" in
	 *      a JSP page.
	 * @return The authorization token if authenticated, otherwise
	 *      <code>null</code>.
	 * @see SkinUtils#getUserAuthorization(HttpServletRequest,HttpServletResponse,boolean)
	 */
	public UserSession getUserAuthorization(HttpServletRequest request, HttpServletResponse response) {
		return getUserAuthorization(request, response, true);
	}

	public void refreshUserAuthorization(HttpServletRequest request, HttpServletResponse response) {
		UserSession auth = getUserAuthorization(request, response);
		setAuthorizationData(auth);
	}

	/**
	 * Validates the user and optionally enables auto-login by creating an
	 * auto-login cookie.
	 * 
	 * @param request
	 *            the HttpServletRequest object, known as "request" in a JSP
	 *            page.
	 * @param response
	 *            the HttpServletResponse object, known as "response" in a JSP
	 *            page.
	 * @param emailAddr
	 *            the emailAddr.
	 * @param password
	 *            the password.
	 * @param autoLogin
	 *            if <code>true</code> create a cookie that enables
	 *            auto-login.
	 * @throws UserNotFoundException
	 * @throws UnauthorizedException
	 * @return The authorization token if authenticated, otherwise
	 *         <code>null</code>
	 */
	public UserSession setUserAuthorization(HttpServletRequest request, HttpServletResponse response, String emailAddr,
			String password, boolean autoLogin) {
		HttpSession session = request.getSession();
		UserSession authToken = this.getAuthorization(emailAddr, password);
		session.setAttribute(JIVE_AUTH_TOKEN, authToken);

		if (response != null && autoLogin) {
			Cookie cookie = new Cookie(JIVE_AUTOLOGIN_COOKIE, encodePasswordCookie(emailAddr, password));
			cookie.setMaxAge(MAX_COOKIE_AGE);
			cookie.setPath("/");
			response.addCookie(cookie);
		}

		return authToken;
	}

	/**
	 * Invalidates the cookie that otherwise lets a user auto-login.
	 * 
	 * @param request
	 *            The HttpServletRequest object, known as "request" in a JSP
	 *            page.
	 * @param response
	 *            The HttpServletResponse object, known as "response" in a JSP
	 *            page.
	 */
	public void removeUserAuthorization(HttpServletRequest request, HttpServletResponse response) {
		HttpSession session = request.getSession();
		session.removeAttribute(JIVE_AUTH_TOKEN);
		Cookie cookie = new Cookie(JIVE_AUTOLOGIN_COOKIE, null);
		cookie.setMaxAge(0);
		cookie.setPath("/");
		response.addCookie(cookie);
	}

	public void userLogout(HttpServletRequest request, HttpServletResponse response) {
		UserSession auth = new UserSession();
		auth.setLogout(true);
		HttpSession session = request.getSession();
		session.setAttribute(JIVE_AUTH_TOKEN, auth);
		// session.removeAttribute(JIVE_AUTH_TOKEN);
	}

	/**
	 * Invalidate the specified cookie and delete it from the response object.
	 * 
	 * @param request
	 *            The HttpServletRequest object, known as "request" in a JSP
	 *            page.
	 * @param response
	 *            The HttpServletResponse object, known as "response" in a JSP
	 *            page.
	 * @param cookieName
	 *            The name of the cookie you want to delete.
	 */
	public void invalidateCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) {
		Cookie cookie = new Cookie(cookieName, null); // invalidate cookie
		cookie.setMaxAge(0); // deletes cookie
		cookie.setPath("/");
		response.addCookie(cookie);
	}

	/**
	 * Persists a value for the length of the user's session.
	 * 
	 * @see SkinUtils#store(HttpServletRequest,HttpServletResponse,String,String,int)
	 *      store
	 */
	public void store(HttpServletRequest request, HttpServletResponse response, String id, String value) {
		store(request, response, id, value, 0, false);
	}

	/**
	 * Persists a value for the time (in seconds) specified
	 * 
	 * @see SkinUtils#store(HttpServletRequest,HttpServletResponse,String,String,int)
	 *      store
	 */
	public void store(HttpServletRequest request, HttpServletResponse response, String id, String value, int secsToLive) {
		store(request, response, id, value, secsToLive, false);
	}

	public void store(HttpServletRequest request, HttpServletResponse response, String id, Object value,
			int secsToLive, boolean restoreInSession) {
		String sv = "";
		if (value instanceof Integer) {
			sv = String.valueOf(((Integer) value));
		} else if (value instanceof Long) {
			sv = String.valueOf(((Long) value));
		}
		if (value instanceof String) {
			sv = (String) value;
		} else {
			logger.error("UnSupported Value Type");
		}
		store(request, response, id, sv, secsToLive, restoreInSession);
	}

	/**
	 * This method should be used in a jsp skin to store an arbritary value. For
	 * example, we could persist the name of a user so that on a form page where
	 * they enter their name, that field could be auto-filled in with the stored
	 * value.
	 * <p>
	 * To indicate that the data should only be persisted for a session, pass in
	 * 0 as the <code>timeToLive</code>.
	 * 
	 * @param request
	 *            The HttpServletRequest object, known as "request" on a JSP
	 *            page.
	 * @param response
	 *            The HttpServletRequest object, known as "response" on a JSP
	 *            page.
	 * @param id
	 *            The name or identifier of the data you want to persist.
	 * @param value
	 *            The value you wish to store.
	 * @param secsToLive
	 *            The length (in seconds) this value will persist. Any value of
	 *            0 or less indicates this data should only persist for a
	 *            session.
	 */
	public void store(HttpServletRequest request, HttpServletResponse response, String id, String value,
			int secsToLive, boolean restoreInSession) {
		// This method uses sessions and cookies to persist data. We always
		// store
		// it in the user's session. We'll only set it in a cookie if the
		// 'timeToLive' parameter is > 0.

		// If the id is null, return
		if (id == null) {
			return;
		}

		// Get the session object:
		HttpSession session = request.getSession();

		// check to see if the value already exists in the session -- if it
		// does,
		// don't restore it unless specified
		if (((String) session.getAttribute(id)) != null && !restoreInSession) {
			return;
		}

		// At this point, restore (or store for the first time) the value in the
		// session
		// Servlet API 2.1 call. Used to preserve compatibility with older app
		// servers. You might get deprecation warnings.
		session.setAttribute(id, value);

		// if the timeToLive param is > 0, store to the cookie:
		if (secsToLive > 0) {
			// Check to make sure the new value is not null (appservers like
			// Tomcat
			// 4 blow up if the value is null).
			if (value == null) {
				value = "";
			}
			Cookie cookie = new Cookie(id, value);
			cookie.setMaxAge(secsToLive);
			cookie.setPath("/");
			response.addCookie(cookie);
		}
	}

	/**
	 * Retrieves a user stored value. Values are set using the
	 * <code>store(...)</code> methods.
	 * 
	 * @param request
	 *            The HttpServletRequest object, known as "request" on a JSP
	 *            page.
	 * @param response
	 *            The HttpServletRequest object, known as "response" on a JSP
	 *            page.
	 * @param id
	 *            The id or name of the stored value.
	 * @return The value of the specified id, otherwise <code>null</code>.
	 */
	public String retrieve(HttpServletRequest request, HttpServletResponse response, String id) {
		// just retrieve the value, don't remove it from persistence
		return (retrieve(request, response, id, false));
	}

	/**
	 * Retrieves a user stored value. Values are set using the
	 * <code>store(...)</code> methods. If <code>remove</code> is true, the
	 * value is also removed from persistence.
	 * 
	 * @param request
	 *            The HttpServletRequest object, known as "request" on a JSP
	 *            page.
	 * @param response
	 *            The HttpServletRequest object, known as "response" on a JSP
	 *            page.
	 * @param id
	 *            The id or name of the stored value.
	 * @return The value of the specified id, otherwise <code>null</code>.
	 */
	public String retrieve(HttpServletRequest request, HttpServletResponse response, String id, boolean remove) {
		// First, check the session.
		HttpSession session = request.getSession();
		String value = (String) session.getAttribute(id);

		// if it's not found, check the cookies
		if (value == null) {
			value = getCookieValue(request, id);
		}

		// remove it from persistence if indicated
		if (remove) {
			remove(request, response, id);
		}

		return value;
	}

	/**
	 * Removes a user stored value. Values are set using the
	 * <code>store(...)</code> methods.
	 * 
	 * @param request
	 *            the HttpServletRequest object, known as "request" on a JSP
	 *            page.
	 * @param response
	 *            the HttpServletRequest object, known as "response" on a JSP
	 *            page.
	 * @param id
	 *            the id or name of the stored value you wish to remove from
	 *            persistence.
	 */
	public void remove(HttpServletRequest request, HttpServletResponse response, String id) {
		// First, remove it from the session:
		HttpSession session = request.getSession();
		session.removeAttribute(id);

		// Invalidate the cookie by setting a null expired cookie in its place
		Cookie cookie = new Cookie(id, null);
		cookie.setMaxAge(0);
		cookie.setPath("/");
		response.addCookie(cookie);
	}

	/**
	 * Returns the time in milliseconds that the user last visited Jive.
	 * 
	 * @param request
	 *            the HttpServletRequest object, known as "request" on a JSP
	 *            page.
	 * @param response
	 *            the HttpServletRequest object, known as "response" on a JSP
	 *            page.
	 * @see SkinUtils#getLastVisited(HttpServletRequest,HttpServletResponse,boolean)
	 *      getLastVisited
	 * @return The time (in milliseconds) that the suer last visited Jive.
	 */
	public long getLastVisited(HttpServletRequest request, HttpServletResponse response) {
		return getLastVisited(request, response, true);
	}

	/**
	 * Returns the time in milliseconds that the user last visited the Jive
	 * system.
	 * 
	 * @param request
	 *            the HttpServletRequest object, known as "request" on a JSP
	 *            page.
	 * @param response
	 *            the HttpServletRequest object, known as "response" on a JSP
	 *            page.
	 * @param updateLastVisitedTime
	 *            Set to <code>true</code> if you wish to update the user's
	 *            last visited time to the current time; set to
	 *            <code>false</code> otherwise.
	 * @return The time (in milliseconds) that the suer last visited Jive.
	 */
	public long getLastVisited(HttpServletRequest request, HttpServletResponse response, boolean updateLastVisitedTime) {
		// Get session object
		HttpSession session = request.getSession();

		// The current instant in time.
		long now = System.currentTimeMillis();

		// First, try to retrieve the value from the session
		String lastTime = (String) session.getAttribute(JIVE_LASTVISITED_TOKEN);

		// Found a value in the session, so return it
		if (lastTime != null) {
			try {
				long time = Long.parseLong(lastTime);
				// update the last visited time to now, but don't update the
				// last visited time in the session:
				Cookie cookie = new Cookie(JIVE_LASTVISITED_TOKEN, Long.toString(now));
				cookie.setMaxAge(60 * 60 * 24 * 30);
				cookie.setPath("/");
				response.addCookie(cookie);
				// return the time value
				return time;
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}

		// getting to this point means no time value was found in the session,
		// so look for it in the cookie:
		long time = now;
		lastTime = getCookieValue(request, JIVE_LASTVISITED_TOKEN);
		if (lastTime != null) {
			try {
				time = Long.parseLong(lastTime);
			} catch (NumberFormatException e) {
			}
		}

		// set the value in the cookie, return the time
		session.setAttribute(JIVE_LASTVISITED_TOKEN, Long.toString(time));
		Cookie cookie = new Cookie(JIVE_LASTVISITED_TOKEN, Long.toString(now));
		cookie.setMaxAge(60 * 60 * 24 * 30);
		cookie.setPath("/");
		response.addCookie(cookie);

		return time;
	}

	/**
	 * Returns the time in milliseconds that the user last visited the Jive
	 * system.
	 * 
	 * @param request
	 *            the HttpServletRequest object, known as "request" on a JSP
	 *            page.
	 * @param response
	 *            the HttpServletRequest object, known as "response" on a JSP
	 *            page.
	 * @param updateLastVisitedTime
	 *            Set to <code>true</code> if you wish to update the user's
	 *            last visited time to the current time; set to
	 *            <code>false</code> otherwise.
	 * @return The time (in milliseconds) that the suer last visited Jive.
	 */
	public void setLastVisitedHorde(HttpServletRequest request, HttpServletResponse response) {
		// Get session object
		HttpSession session = request.getSession();

		// The current instant in time.
		long now = System.currentTimeMillis();

		// First, try to retrieve the value from the session
		Store lastVisitedHorde = (Store) session.getAttribute(JIVE_LASTVISITED_HORDE_TOKEN);

		Long currentVisitedHordeId = ServletRequestUtils.getLongParameter(request, "ssid", -1);

		if (lastVisitedHorde == null || lastVisitedHorde != null
				&& currentVisitedHordeId.compareTo(lastVisitedHorde.getSysId()) != 0) {
			lastVisitedHorde = storeDao.find(currentVisitedHordeId);
			if (lastVisitedHorde != null) {
				// set the value in the cookie, return the time
				session.setAttribute(JIVE_LASTVISITED_HORDE_TOKEN, lastVisitedHorde);
				Cookie cookie = new Cookie(JIVE_LASTVISITED_HORDE_TOKEN, Long.toString(currentVisitedHordeId));
				cookie.setMaxAge(60 * 60 * 24 * 30);
				cookie.setPath("/");
				response.addCookie(cookie);
			}
		}
	}

	public void setHasCheckedAutoLogin(HttpServletRequest request, HttpServletResponse response) {
		// set session object
		HttpSession session = request.getSession();
		session.setAttribute(JIVE_HAS_CHECKED_AUTOLOGIN_TOKEN, new Boolean(true));
	}

	public Store getLastVisitedHorde(HttpServletRequest request, HttpServletResponse response) {
		// Get session object
		HttpSession session = request.getSession();
		Store lastVisitedHorde = (Store) session.getAttribute(JIVE_LASTVISITED_HORDE_TOKEN);
		if (lastVisitedHorde == null) {
			String lastVisitedHordeIdStr = this.getCookieValue(request, JIVE_LASTVISITED_HORDE_TOKEN);
			if (lastVisitedHordeIdStr != null) {
				Long lastVisitedHordeId = Long.parseLong(lastVisitedHordeIdStr);
				lastVisitedHorde = storeDao.find(lastVisitedHordeId);
				session.setAttribute(JIVE_LASTVISITED_HORDE_TOKEN, lastVisitedHorde);
			}
		}

		return lastVisitedHorde;
	}

	/**
	 * Returns the specified Cookie object, or null if the cookie does not
	 * exist.
	 * 
	 * @param request
	 *            The HttpServletRequest object, known as "request" in a JSP
	 *            page.
	 * @param name
	 *            the name of the cookie.
	 * @return the Cookie object if it exists, otherwise null.
	 */
	public Cookie getCookie(HttpServletRequest request, String name) {
		Cookie cookies[] = request.getCookies();
		if (cookies == null || name == null || name.length() == 0) {
			return null;
		}
		// Otherwise, we have to do a linear scan for the cookie.
		for (int i = 0; i < cookies.length; i++) {
			if (cookies[i].getName().equals(name)) {
				return cookies[i];
			}
		}
		return null;
	}

	/**
	 * Returns the value of the specified cookie as a String. If the cookie does
	 * not exist, the method returns null.
	 * 
	 * @param request
	 *            the HttpServletRequest object, known as "request" in a JSP
	 *            page.
	 * @param name
	 *            the name of the cookie
	 * @return the value of the cookie, or null if the cookie does not exist.
	 */
	public String getCookieValue(HttpServletRequest request, String name) {
		Cookie cookie = getCookie(request, name);
		if (cookie != null) {
			return cookie.getValue();
		}
		return null;
	}

	/**
	 * Returns a String describing the amount of time between now (current
	 * system time) and the passed in date time. Example output is "5 hours ago"
	 * or "Yesterday at 3:30 pm"
	 * 
	 * @param date
	 *            the Date to compare the current time with.
	 * @return a description of the difference in time, ie: "5 hours ago" or
	 *         "Yesterday at 3:30pm"
	 */
	public String dateToText(Date date) {
		if (date == null) {
			return "";
		}

		long delta = System.currentTimeMillis() - date.getTime();

		// within the last hour
		if ((delta / HOUR) < 1) {
			long minutes = (delta / MINUTE);
			if (minutes == 0) {
				return "Less than 1 min ago";
			} else if (minutes == 1) {
				return "1 minute ago";
			} else {
				return (minutes + " minutes ago");
			}
		}

		// sometime today
		if ((delta / DAY) < 1) {
			long hours = (delta / HOUR);
			if (hours <= 1) {
				return "1 hour ago";
			} else {
				return (hours + " hours ago");
			}
		}

		// within the last week
		if ((delta / WEEK) < 1) {
			double days = ((double) delta / (double) DAY);
			if (days <= 1.0) {
				return yesterdayFormatter.format(date);
			} else {
				return dateFormatter.format(date);
			}
		}

		// before a week ago
		else {
			return dateFormatter.format(date);
		}
	}

	/**
	 * Builds a cookie string containing a username and password.
	 * <p>
	 * 
	 * Note: with open source this is not really secure, but it prevents users
	 * from snooping the cookie file of others and by changing the XOR mask and
	 * character offsets, you can easily tweak results.
	 * 
	 * @param username
	 *            The username.
	 * @param password
	 *            The password.
	 * @return String encoding the input parameters, an empty string if one of
	 *         the arguments equals <code>null</code>.
	 */
	private String encodePasswordCookie(String username, String password) {
		StringBuffer buf = new StringBuffer();
		if (username != null && password != null) {
			byte[] bytes = (username + ENCODE_DELIMETER + password).getBytes();
			int b;

			for (int n = 0; n < bytes.length; n++) {
				b = bytes[n] ^ (ENCODE_XORMASK + n);
				buf.append((char) (ENCODE_CHAR_OFFSET1 + (b & 0x0F)));
				buf.append((char) (ENCODE_CHAR_OFFSET2 + ((b >> 4) & 0x0F)));
			}
		}
		return buf.toString();
	}

	/**
	 * Unrafels a cookie string containing a username and password.
	 * 
	 * @param value
	 *            The cookie value.
	 * @return String[] containing the username at index 0 and the password at
	 *         index 1, or <code>{ null, null }</code> if cookieVal equals
	 *         <code>null</code> or the empty string.
	 */
	private String[] decodePasswordCookie(String cookieVal) {

		// check that the cookie value isn't null or zero-length
		if (cookieVal == null || cookieVal.length() <= 0) {
			return null;
		}

		// unrafel the cookie value
		char[] chars = cookieVal.toCharArray();
		byte[] bytes = new byte[chars.length / 2];
		int b;
		for (int n = 0, m = 0; n < bytes.length; n++) {
			b = chars[m++] - ENCODE_CHAR_OFFSET1;
			b |= (chars[m++] - ENCODE_CHAR_OFFSET2) << 4;
			bytes[n] = (byte) (b ^ (ENCODE_XORMASK + n));
		}
		cookieVal = new String(bytes);
		int pos = cookieVal.indexOf(ENCODE_DELIMETER);
		String username = (pos < 0) ? "" : cookieVal.substring(0, pos);
		String password = (pos < 0) ? "" : cookieVal.substring(pos + 1);

		return new String[] { username, password };
	}

	/**
	 * compute page footer parameters
	 * 
	 * @param request
	 * @param pageItemNum
	 * @param totalItemNum
	 * @param pgno
	 * @param pgsize
	 * @param otherParam e.g. a=1&b=3&cpid=paramvalue
	 * @param model
	 * @return
	 */
	public Map<String, Object> preparePageFooterParameters(HttpServletRequest request, int pageItemNum,
			long totalItemNum, int pgno, int pgsize, String otherParam, Map<String, Object> model) {
		Long totalPage = new Long(totalItemNum / pgsize + (totalItemNum % pgsize > 0 ? 1 : 0));

		int pgnumber = 5; // total pages index on footer
		Integer startPgno = pgno / pgnumber * pgnumber + 1;
		Long endPgno = (pgno / pgnumber + 1) * pgnumber > totalPage ? totalPage : (pgno / pgnumber + 1) * pgnumber;

		String url = request.getRequestURI();
		if (otherParam != null)
			url += "?" + otherParam + "&";
		else
			url += "?";
		model.put("pageUrl", url);
		model.put("pgno", pgno);
		model.put("pgsize", pgsize);
		model.put("pgnumber", pgnumber);
		model.put("count", totalItemNum);
		model.put("startIdx", pgno * pgsize + 1);
		model.put("endIdx", pgno * pgsize + pageItemNum);
		model.put("startPgno", startPgno);
		model.put("endPgno", endPgno);
		model.put("totalpage", totalPage);
		logger.info("preparePageFooter parameters: requestURI=" + request.getRequestURI() + " pgno=" + pgno + " count="
				+ totalItemNum + " startIdx=" + pgno * pgsize + 1 + " endIdx=" + pgno * pgsize + pageItemNum
				+ " startPgno=" + startPgno + " endPgno=" + endPgno + " totalpage=" + totalPage);
		return model;

	}

	/**
	 * test method for this class
	 */
	/*
	 * public static void main( String args[] ) { Calendar cal =
	 * Calendar.getInstance(); System.out.println( "now:\t" +
	 * dateToText(cal.getTime()) ); for( int i=0; i<122; i++ ) { cal.setTime(
	 * new Date(cal.getTime().getTime() - (30*MINUTE) ) ); System.out.println(
	 * (i+1) + " min ago:\t" + dateToText(cal.getTime()) + "\t" + cal.getTime() ); } }
	 */

	public UserSession getAuthorization(String emailAddr, String password) {
		User user = userDao.find(emailAddr);
		UserSession auth = null;
		if (user != null && password != null && password.equals(user.getPassword())) {
			// logger.info("***************************prepare
			// Authorization*********************");
			auth = new UserSession();
			auth.setUserSysId(user.getSysId());
			auth.setUserNickName(user.getNickName());
			auth.setUserId(user.getId());

			if (emailAddr.equals(rootUserId)) {
				auth.setRootUser(true);
			}

			setAuthorizationData(auth);

		}
		return auth;
	}

	private void setAuthorizationData(UserSession auth) {
		// set user managed store info
		User user = userDao.find(auth.getUserSysId());

		Store userManagedStore = user.getManagedStore();
		if (userManagedStore != null) {
			auth.setManagedStoreSysId(userManagedStore.getSysId());
			auth.setManagedStoreName(userManagedStore.getName());
			// we need to check whether userManagedStore has been authorized to
			// be online
			if (userManagedStore.getStatus() != null
					&& userManagedStore.getStatus().compareTo(BusinessConstant.Status.IS_APPROVE_SUCC.getId()) == 0) {
				auth.setManagedStoreOnline(true);
			}
		} else {
			auth.setManagedStoreSysId(-1);
			auth.setManagedStoreName("");
			auth.setManagedStoreOnline(false);
		}

		if(user.isSupplier()){
			auth.setSupplierUser(true);
		}else{
			auth.setSupplierUser(false);			
		}
		
		if(user.isServant()){
			auth.setServantUser(true);
		}else{
			auth.setServantUser(false);
		}
	}

	/**
	 * get  product  sysid parameter from http request, the parameter name is "prdsid"
	 * 
	 * @param request
	 * @return
	 */
	public Long getParameterProductSysId(HttpServletRequest request) {
		Long brdsid = ServletRequestUtils.getLongParameter(request, "prdsid", -1);
		return brdsid;
	}

	/**
	 * get  store  sysid parameter from http request, the parameter name is "stosid"
	 * 
	 * @param request
	 * @return
	 */
	public Long getParameterStoreSysId(HttpServletRequest request) {
		Long stosid = ServletRequestUtils.getLongParameter(request, "stosid", -1);
		return stosid;
	}

	/**
	 * get  brand  sysid parameter from http request, the parameter name is "brdsid"
	 * 
	 * @param request
	 * @return long brdsid value
	 */
	public Long getParameterBrandSysId(HttpServletRequest request) {
		Long brdsid = ServletRequestUtils.getLongParameter(request, "brdsid", -1);
		return brdsid;
	}

	/**
	 * get product category sysid parameter from http request, the parameter name is "pdgsid"
	 * 
	 * @param request
	 * @return long pdgsid value
	 */
	public Long getParameterProductCategorySysId(HttpServletRequest request) {
		Long pdgsid = ServletRequestUtils.getLongParameter(request, "pdgsid", -1);
		if (pdgsid == -1) {
			Category topProductCat = categoryDao.find(BusinessConstant.CategoryID.PRODUCT_CATEGORY_TOP.getId());
			if (topProductCat != null) {
				pdgsid = topProductCat.getSysId();
			}
		}
		return pdgsid;
	}

	/**
	 * get store area category sysid parameter from http request, the parameter name is "argsid"
	 * 
	 * @param request
	 * @return long argsid value
	 */
	public Long getParameterAreaCategorySysId(HttpServletRequest request) {
		Long argsid = ServletRequestUtils.getLongParameter(request, "argsid", -1);
		if (argsid == -1) {
			Category topProductCat = categoryDao.find(BusinessConstant.CategoryID.AREA_CATEGORY_TOP.getId());
			if (topProductCat != null) {
				argsid = topProductCat.getSysId();
			}
		}
		return argsid;
	}

	/**
	 * get website category sysid parameter from http request, the parameter name is "wsgsid"
	 * 
	 * @param request
	 * @return long argsid value
	 */
	public Long getParameterWebsiteCategorySysId(HttpServletRequest request) {
		Long argsid = ServletRequestUtils.getLongParameter(request, "wsgsid", -1);
		if (argsid == -1) {
			Category topProductCat = categoryDao.find(BusinessConstant.CategoryID.WEBSITE_CATEGORY_TOP.getId());
			if (topProductCat != null) {
				argsid = topProductCat.getSysId();
			}
		}
		return argsid;
	}

	/**
	 * get store area category sysid parameter from http request, the parameter name is "bsgsid"
	 * 
	 * @param request
	 * @return long bsgsid value
	 */
	public Long getParameterBusinessCategorySysId(HttpServletRequest request) {
		Long bsgsid = ServletRequestUtils.getLongParameter(request, "bsgsid", -1);
		if (bsgsid == -1) {
			Category topProductCat = categoryDao.find(BusinessConstant.CategoryID.BUSINESS_CATEGORY_TOP.getId());
			if (topProductCat != null) {
				bsgsid = topProductCat.getSysId();
			}
		}
		return bsgsid;
	}

	public UserBusiness getUserBusiness() {
		return userBusiness;
	}

	public void setUserBusiness(UserBusiness userBusiness) {
		this.userBusiness = userBusiness;
	}

	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	public void setRootUserId(String rootUserId) {
		this.rootUserId = rootUserId;
	}

	public Logger getLogger() {
		return logger;
	}

	public void setLogger(Logger logger) {
		this.logger = logger;
	}

	/**
	 * @param storeDao the storeDao to set
	 */
	public void setStoreDao(StoreDao storeDao) {
		this.storeDao = storeDao;
	}

	/**
	 * @param categoryDao the categoryDao to set
	 */
	public void setCategoryDao(CategoryDao categoryDao) {
		this.categoryDao = categoryDao;
	}

}